﻿using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System.Net;
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Text;
using System.Web;

namespace SwaggerSdk
{

    /************
         * 调试提醒，如果服务端接收不到参数请个传输类型，可以打印出来，也可以借用Fiddler工具查看
         * **************/
    public class HttpHelper
    {
        private readonly HttpClient _httpClient;
        private readonly IConfiguration _configuration;
        private readonly string _baseUrl;
        private readonly string _token;
        public HttpHelper(HttpClient httpClient, IConfiguration configuration)
        {
            _httpClient = httpClient;
            _configuration = configuration;
            _baseUrl = _configuration["BaseUrl"] ?? "";
            _token = _configuration["Token"];
            Console.WriteLine("读取Token=" + _token);
            // 设置 HttpClient 的基础地址
            _httpClient.BaseAddress = new Uri(_baseUrl);
            // 设置请求头
            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);
        }
        public async Task<Stream> DownloadAsync(string endpoint, Dictionary<string, string> queryParams = null)
        {
            try
            {
                // 构建完整的 URL
                var url = BuildUrlWithParams(endpoint, queryParams);

                var response = await _httpClient.GetAsync(url);

                response.EnsureSuccessStatusCode();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    return await response.Content.ReadAsStreamAsync();
                }
                else
                    return new MemoryStream();
                
            }
            catch (Exception ex)
            {

                throw;
            }

        }
        public async Task<T> GetAsync<T>(string endpoint, Dictionary<string, string> queryParams=null)
        {
            try
            {
                // 构建完整的 URL
                var url = BuildUrlWithParams(endpoint, queryParams);

                var response = await _httpClient.GetAsync(url);
              
                response.EnsureSuccessStatusCode();

                var rspcontent = await response.Content.ReadAsStringAsync();
                return CallBackResult<T>(rspcontent);
            }
            catch (Exception ex)
            {

                throw;
            }
            
        }
        public async Task<T> GetAsync<T>(string endpoint, object obj)
        {
            try
            {
                // 构建完整的 URL
                var url = BuildObjectParams(endpoint, obj);

                var response = await _httpClient.GetAsync(url);

                response.EnsureSuccessStatusCode();

                var rspcontent = await response.Content.ReadAsStringAsync();
                return CallBackResult<T>(rspcontent);
            }
            catch (Exception ex)
            {

                throw;
            }

        }

        /************
         * 调试提醒，如果服务端接收不到参数请个传输类型，可以打印出来，也可以借用Fiddler工具查看
         * **************/

        /// <summary>
        /// 接收端为
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="endpoint"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<T> PostAsync<T>(string endpoint, object data)
        {
            var json = JsonConvert.SerializeObject(data);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            var response = await _httpClient.PostAsync(endpoint, content);
            response.EnsureSuccessStatusCode();

            var rspcontent = await response.Content.ReadAsStringAsync();
            return CallBackResult<T>(rspcontent);
        }

        /// <summary>
        /// post对象表单提交
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="endpoint"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<T> PostObjectAsync<T>(string endpoint, object data)
        {
            var formData = new List<KeyValuePair<string, string>>();

            // 将对象的属性转换为键值对形式
            foreach (var prop in data.GetType().GetProperties())
            {
                var value = prop.GetValue(data)?.ToString();
                if (value != null)
                {
                    formData.Add(new KeyValuePair<string, string>(prop.Name, value));
                }
            }
            var content = new FormUrlEncodedContent(formData);

            var response = await _httpClient.PostAsync(endpoint, content);
            response.EnsureSuccessStatusCode();

            var rspcontent = await response.Content.ReadAsStringAsync();
            return CallBackResult<T>(rspcontent);
        }

        public async Task<T> PostAsync<T>(string endpoint, Dictionary<string, string> formData)
        {
            var content = new FormUrlEncodedContent(formData);
            var requestMessage = new HttpRequestMessage(HttpMethod.Post, endpoint)
            {
                Content = new FormUrlEncodedContent(formData)
            };
            // 打印请求头以确认 Content-Type 是否正确
            //Console.WriteLine("Request Content-Type: " + requestMessage.Content.Headers.ContentType);

            var response = await _httpClient.SendAsync(requestMessage);
            response.EnsureSuccessStatusCode();

            var rspcontent = await response.Content.ReadAsStringAsync();
            return CallBackResult<T>(rspcontent);
        }


        private T CallBackResult<T>(string rspcontent)
        {
            if (string.IsNullOrEmpty(rspcontent))
            {
                throw new InvalidOperationException("异常:返回值为空");
            }
            var result = JsonConvert.DeserializeObject<T>(rspcontent);
            if (result == null)
            {
                throw new InvalidOperationException("异常:返回值为空");
            }
           
            return result;
        }

        private string BuildUrlWithParams(string endpoint, Dictionary<string, string> queryParams)
        {
            if (queryParams == null || queryParams.Count == 0)
                return endpoint;

            var queryString = string.Join("&", queryParams.Select(kv => $"{kv.Key}={WebUtility.UrlEncode(kv.Value)}"));
            return $"{endpoint}?{queryString}";
        }
        private static string BuildObjectParams(string endpoint, object obj)
        {
            if (obj == null)
                return endpoint;
            var properties = obj.GetType().GetProperties();
            var query = new StringBuilder();

            foreach (var property in properties)
            {
                var value = property.GetValue(obj, null);
                if (value != null)
                {
                    query.AppendFormat("&{0}={1}", property.Name, WebUtility.UrlEncode(value.ToString()));
                }
            }

            if (query.Length > 0)
            {
                query.Remove(0, 1); // Remove the leading '&'
            }
            return $"{endpoint}?{query.ToString()}";
        }
    }
}
